#include <vector>
#include <queue>
#include "sched_rr.h"
#include "basesched.h"
#include <iostream>
#include <fstream>

using namespace std;

SchedRR::SchedRR(vector<int> argn) {
	// Round robin recibe la cantidad de cores y sus cpu_quantum por parámetro
	cores = argn[0];
	for(int i = 0; i < cores; i++ ){
		quantum.push_back(argn[i+1]);
		quantum_left.push_back(argn[i+1]);
	}
	
	
	vector<int> t(5);
	
	for(int i = 0; i < cores; i++ ){
		
		t.push_back(0);
	}
	
	for(int i = 0; i < 5; i++ ){
		
		ready_tarea_cpu.push_back(0);
	}
	
	for(int i = 0; i < cores; i++ ){
		vector<int> temp = t;
		Cont_cpu_tarea.push_back(temp);
	}
	for(int i = 0; i < cores; i++ ){
		current_tick_by_cpu.push_back(0);
	}
	
}

SchedRR::~SchedRR() {
	//~ std::ofstream ss;

	
	std::ofstream myfile;
	std::ofstream myfile2;
	myfile2.open("RR_ecuanimidad.txt",ios_base::app);
	myfile.open("RR_Promedio.txt",ios_base::app);
	for(int i = 0; i < cores; i++){
	
		myfile2 << "CPU " << i <<" - " << " quantum:" << quantum[i] << ": ";
		myfile2 << Cont_cpu_tarea[i][0] <<" " << Cont_cpu_tarea[i][1] << " " << Cont_cpu_tarea[i][2] << " " << Cont_cpu_tarea[i][3] << " " << Cont_cpu_tarea[i][4] << " " << endl;
		
	}
	//~ myfile<< endl;
	myfile <<"Tiempo Ejec con Q:" << quantum[0] << ": ";
	for(int j=0; j< 5; j++){
		
		myfile<< ready_tarea_cpu[j] << " ";
		
	}
	myfile<< endl;
	
	

	//~ cout <<"Cerrando logs" <<endl;
	myfile2.close();
	myfile.close();
}


void SchedRR::load(int pid) {
	tareas.push(pid);
}

void SchedRR::unblock(int pid) {
	load(pid);
}

int SchedRR::tick(int cpu, const enum Motivo m) {
	
	current_tick_by_cpu[cpu] ++;
	if(m == TICK && (current_pid(cpu)!=IDLE_TASK)){
		
		//cuando la tarea hace tick por primera vez
		if(ready_tarea_cpu[current_pid(cpu)]==0){
				ready_tarea_cpu[current_pid(cpu)] = current_tick_by_cpu[cpu];
		}
		
		//suma la vez q le toco CPU
		if(quantum[cpu] == quantum_left[cpu]){
				Cont_cpu_tarea[cpu][current_pid(cpu)]++;
		}
		
		//resto 1 al quantum_left[cpu]
		quantum_left[cpu]--; 
		//si no queda quantum, restauro el quantum y pido la proxima tarea --> next()
		
		if(quantum_left[cpu] == 0){
			tareas.push(current_pid(cpu));
			return next(cpu);
		}else {
			return current_pid(cpu);
		}
	}
	// Si es BLOCK o EXIT, solo pido next()
	if(m==EXIT && (current_pid(cpu)!=IDLE_TASK)){
		//guardo tiempo de ejecucion = tiempo fin - tiempo inicio
		ready_tarea_cpu[current_pid(cpu)] = current_tick_by_cpu[cpu] - ready_tarea_cpu[current_pid(cpu)]  ;
		}
	return next(cpu);
}

int SchedRR::next(int cpu) {
	//restauro el quantum_left
		if(tareas.empty()){
			quantum_left[cpu] = quantum[cpu];
			return IDLE_TASK;
	}else {
		int next_task = tareas.front();
		tareas.pop();
		quantum_left[cpu] = quantum[cpu];
		return next_task;
	}
	
}
